package lxs.swift.tool.http;

import java.io.UnsupportedEncodingException;
import java.net.Proxy;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class Config {
    protected URI uri;
    protected final Map<String, List<Object>> headerMap;
    protected final Map<String, Object> params = new HashMap<>();
    protected int connectTimeout = Integer.MAX_VALUE;
    protected int readTimeout = Integer.MAX_VALUE;
    protected String method = "";
    protected Charset charset = StandardCharsets.UTF_8;
    protected Proxy proxy = Proxy.NO_PROXY;

    protected Config(String url) {
        this.uri = URI.create(url);
        String protocol = this.uri.getScheme();
        if ("https".equalsIgnoreCase(protocol)) {
            Sender.trustAllHttpsCertificates();
        }
        this.headerMap = new HashMap<>();
    }

    public static Config of(String url) {
        return new Config(url);
    }

    public Config headers(Map<String, Object> headerMap) {
        headerMap.forEach((k, v) -> {
            this.headerMap.computeIfAbsent(k, k1 -> new ArrayList<>()).add(v);
        });
        return this;
    }

    public String assembleURL() {
        String urlStr = uri.toString();
        if (!params.isEmpty()) {
            int indexOf = urlStr.indexOf("?");
            if (indexOf != -1) {
                String paramsStr = urlStr.substring(indexOf + 1);
                String[] paramsArr = paramsStr.split("&");
                for (String param : paramsArr) {
                    if (param.isEmpty()) continue;
                    String[] split = param.split("=");
                    if (split[0].isEmpty()) throw new RuntimeException("URL格式错误");
                    if (split[1].isEmpty()) continue;
                    params.put(split[0], split[1]);
                }
                urlStr = urlStr.substring(0, indexOf);
            }
            String[] strings = new String[params.size()];
            int index = 0;
            for (String k : params.keySet()) {
                Object v = params.get(k);
                if (v == null) continue;
                try {
                    strings[index] = k + "=" + URLEncoder.encode(v.toString(), "UTF8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
                index++;
            }
            urlStr += ("?" + String.join("&", strings));
        }

        return urlStr;
    }

    public Config header(String key, Object value) {
        if (key == null || key.isEmpty() || value == null) return this;
        this.headerMap.computeIfAbsent(key, k1 -> new ArrayList<>()).add(value);
        return this;
    }

    public Config connectTimeout(int millisecond) {
        this.connectTimeout = millisecond;
        return this;
    }

    public Config readTimeout(int millisecond) {
        this.readTimeout = millisecond;
        return this;
    }

    public Config method(String method) {
        Objects.requireNonNull(method);
        this.method = method;
        return this;
    }

    public Config charset(Charset charset) {
        Objects.requireNonNull(charset);
        this.charset = charset;
        return this;
    }

    public Config proxy(Proxy proxy) {
        Objects.requireNonNull(proxy);
        this.proxy = proxy;
        return this;
    }

    public Config param(String key, Object value) {
        if (key == null || key.isEmpty() || value == null || value.toString().isEmpty()) return this;
        this.params.put(key, value);
        return this;
    }

    public Config params(Map<String, Object> params) {
        Objects.requireNonNull(method);
        params.forEach(this::param);
        return this;
    }

}
